home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / timidsrc.zip / common.c < prev    next >
C/C++ Source or Header  |  1996-06-01  |  5KB  |  229 lines

  1. /*
  2.  
  3.     TiMidity -- Experimental MIDI to WAVE converter
  4.     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.    common.c
  21.  
  22.    */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26.  
  27. #if defined(SOLARIS) || defined(__WIN32__)
  28. #include <string.h>
  29. #else
  30. #include <strings.h>
  31. #endif
  32.  
  33. #include <errno.h>
  34. #include "config.h"
  35. #include "common.h"
  36. #include "output.h"
  37. #include "controls.h"
  38.  
  39. /* I guess "rb" should be right for any libc */
  40. #define OPEN_MODE "rb"
  41.  
  42. char *program_name, current_filename[1024];
  43.  
  44. #ifdef DEFAULT_PATH
  45.     /* The paths in this list will be tried whenever we're reading a file */
  46.     static PathList defaultpathlist={DEFAULT_PATH,0};
  47.     static PathList *pathlist=&defaultpathlist; /* This is a linked list */
  48. #else
  49.     static PathList *pathlist=0;
  50. #endif
  51.  
  52. /* Try to open a file for reading. If the filename ends in one of the 
  53.    defined compressor extensions, pipe the file through the decompressor */
  54. static FILE *try_to_open(char *name, int decompress, int noise_mode)
  55. {
  56.   FILE *fp;
  57.  
  58.   fp=fopen(name, OPEN_MODE); /* First just check that the file exists */
  59.  
  60.   if (!fp)
  61.     return 0;
  62.  
  63. #ifdef DECOMPRESSOR_LIST
  64.   if (decompress)
  65.     {
  66.       int l,el;
  67.       static char *decompressor_list[] = DECOMPRESSOR_LIST, **dec;
  68.       char tmp[1024], tmp2[1024], *cp, *cp2;
  69.       /* Check if it's a compressed file */ 
  70.       l=strlen(name);
  71.       for (dec=decompressor_list; *dec; dec+=2)
  72.     {
  73.       el=strlen(*dec);
  74.       if ((el>=l) || (strcmp(name+l-el, *dec)))
  75.         continue;
  76.  
  77.       /* Yes. Close the file, open a pipe instead. */
  78.       fclose(fp);
  79.  
  80.       /* Quote some special characters in the file name */
  81.       cp=name;
  82.       cp2=tmp2;
  83.       while (*cp)
  84.         {
  85.           switch(*cp)
  86.         {
  87.         case '\'':
  88.         case '\\':
  89.         case ' ':
  90.         case '`':
  91.         case '!':
  92.         case '"':
  93.         case '&':
  94.         case ';':
  95.           *cp2++='\\';
  96.         }
  97.           *cp2++=*cp++;
  98.         }
  99.       *cp2=0;
  100.  
  101.       sprintf(tmp, *(dec+1), tmp2);
  102.       fp=popen(tmp, "r");
  103.       break;
  104.     }
  105.     }
  106. #endif
  107.   
  108.   return fp;
  109. }
  110.  
  111. /* This is meant to find and open files for reading, possibly piping
  112.    them through a decompressor. */
  113. FILE *open_file(char *name, int decompress, int noise_mode)
  114. {
  115.   FILE *fp;
  116.   PathList *plp=pathlist;
  117.   int l;
  118.  
  119.   if (!name || !(*name))
  120.     {
  121.       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Attempted to open nameless file.");
  122.       return 0;
  123.     }
  124.  
  125.   /* First try the given name */
  126.  
  127.   strncpy(current_filename, name, 1023);
  128.   current_filename[1023]='\0';
  129.  
  130.   ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
  131.   if ((fp=try_to_open(current_filename, decompress, noise_mode)))
  132.     return fp;
  133.  
  134.   if (noise_mode && (errno != ENOENT))
  135.     {
  136.       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 
  137.        current_filename, sys_errlist[errno]);
  138.       return 0;
  139.     }
  140.   
  141.   if (name[0] != PATH_SEP)
  142.     while (plp)  /* Try along the path then */
  143.       {
  144.     *current_filename=0;
  145.     l=strlen(plp->path);
  146.     if(l)
  147.       {
  148.         strcpy(current_filename, plp->path);
  149.         if(current_filename[l-1]!=PATH_SEP)
  150.           strcat(current_filename, PATH_STRING);
  151.       }
  152.     strcat(current_filename, name);
  153.     ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
  154.     if ((fp=try_to_open(current_filename, decompress, noise_mode)))
  155.       return fp;
  156.     if (noise_mode && (errno != ENOENT))
  157.       {
  158.         ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 
  159.          current_filename, sys_errlist[errno]);
  160.         return 0;
  161.       }
  162.     plp=plp->next;
  163.       }
  164.   
  165.   /* Nothing could be opened. */
  166.  
  167.   *current_filename=0;
  168.   
  169.   if (noise_mode>=2)
  170.     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", name, sys_errlist[errno]);
  171.   
  172.   return 0;
  173. }
  174.  
  175. /* This closes files opened with open_file */
  176. void close_file(FILE *fp)
  177. {
  178. #ifdef DECOMPRESSOR_LIST
  179.   if (pclose(fp)) /* Any better ideas? */
  180. #endif
  181.     fclose(fp);
  182. }
  183.  
  184. /* This is meant for skipping a few bytes in a file or fifo. */
  185. void skip(FILE *fp, size_t len)
  186. {
  187.   size_t c;
  188.   char tmp[1024];
  189.   while (len>0)
  190.     {
  191.       c=len;
  192.       if (c>1024) c=1024;
  193.       len-=c;
  194.       if (c!=fread(tmp, 1, c, fp))
  195.     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: skip: %s",
  196.          current_filename, sys_errlist[errno]);
  197.     }
  198. }
  199.  
  200. /* This'll allocate memory or die. */
  201. void *safe_malloc(size_t count)
  202. {
  203.   void *p;
  204.   if (count > (1<<21))
  205.     {
  206.       ctl->cmsg(CMSG_FATAL, VERB_NORMAL, 
  207.        "Strange, I feel like allocating %d bytes. This must be a bug.",
  208.        count);
  209.     }
  210.   else if ((p=malloc(count)))
  211.     return p;
  212.   else
  213.     ctl->cmsg(CMSG_FATAL, VERB_NORMAL, "Sorry. Couldn't malloc %d bytes.", count);
  214.  
  215.   ctl->close();
  216.   play_mode->purge_output();
  217.   play_mode->close_output();
  218.   exit(10);
  219. }
  220.  
  221. /* This adds a directory to the path list */
  222. void add_to_pathlist(char *s)
  223. {
  224.   PathList *plp=safe_malloc(sizeof(PathList));
  225.   strcpy((plp->path=safe_malloc(strlen(s)+1)),s);
  226.   plp->next=pathlist;
  227.   pathlist=plp;
  228. }
  229.